﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Marmat.Foundation;
using DevExpress.XtraBars;

namespace Marmat.Template.WinForm
{
    /// <summary>
    /// 表单面板控件
    /// </summary>
    public partial class SheetControl : UserControl, IEditFormRoute
    {
        /// <summary>
        /// 构建一个表单面板实例
        /// </summary>
        public SheetControl()
        {
            InitializeComponent();
            //this.panel1.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(this.panel1, true);
        }

        private void SheetControl_Load(object sender, EventArgs e)
        {
            this.SizeChanged += new System.EventHandler(this.SheetControl_SizeChanged);
            //this.panel1.Resize += new System.EventHandler(this.Panel1_Resize);
            this.OnSizeChanged(EventArgs.Empty);
        }

        internal Control Panel { get => this.panel1; }
        private Control control;

        private void SheetControl_Paint(object sender, PaintEventArgs e)
        {
            Rectangle rect = new Rectangle(this.panel1.Left - 1, this.panel1.Top - 1, this.panel1.Width + 1, this.panel1.Height + 1);
            using (Pen pen = new Pen(Color.FromArgb(200, 200, 211)))
            {
                e.Graphics.DrawRectangle(pen, rect);
            }
        }

        private void UpdateLocation()
        {
            //int toolHeight = this.toolStrip1.Visible ? this.toolStrip1.Height : 0;
            int left = Math.Max(20, (this.Width - this.panel1.Width) / 2);
            this.panel1.Left = left - this.HorizontalScroll.Value;
        }

        private void Panel1_Resize(object sender, EventArgs e)
        {
            this.UpdateLocation();
        }

        private void SheetControl_SizeChanged(object sender, EventArgs e)
        {
            this.UpdateLocation();
        }

        Control IEditFormRoute.GetDataPanel()
        {
            return this;
        }

        IEditFormController IEditFormRoute.GetController()
        {
            return this.route.GetController();
        }

        /// <summary>
        /// 路由
        /// </summary>
        private IEditFormRoute route;

        /// <summary>
        /// 设置控制器
        /// </summary>
        /// <param name="controller"></param>
        public void SetController(IEditFormController controller)
        {
            if (controller is Control == false)
                throw new Exception($"{nameof(controller)} 必须 继承于 System.Windows.Forms.Control。");
            if (controller is Control control)
            {
                IEditFormRoute route = new DefaultEditFormRoute(controller, control);
                SetRoute(route);
            }
        }

        /// <summary>
        /// 设置路由
        /// </summary>
        /// <param name="route"></param>
        public void SetRoute(IEditFormRoute route)
        {
            this.route = route;
            Control control = route.GetDataPanel();
            if (control is Form form)
            {
                form.TopLevel = false;
                form.Parent = this;
                form.Visible = true;
                form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
                form.Disposed += this.Form_Disposed;
            }
            this.Text = control.Text;
            control.Location = new Point(0, 0);
            control.ClientSizeChanged += this.Control_ClientSizeChanged;
            control.TextChanged += this.Control_TextChanged;
            this.Panel.Controls.Add(control);
            //this.Size = new Size(this.Panel.Width + 40, this.Panel.Height + 60);
            this.control = control;
            this.Control_ClientSizeChanged(control, EventArgs.Empty);

            IEditFormController controller = route.GetController();
            if (controller is ISheetControl sheet)
            {
                foreach (var item in sheet.ButtonCollection)
                {
                    var button = new System.Windows.Forms.ToolStripButton();
                    button.Name = item.Name;
                    button.Text = item.Caption;
                    button.Tag = item;
                    button.Padding = new Padding(6);
                    button.Margin = new Padding(0, 1, 2, 2);
                    if (item.Icon != null)
                        button.Image = item.Icon;
                    this.toolStrip1.Items.Add(button);
                }
                this.toolStrip1.ItemClicked += ButtonItemClick;
            }
            this.toolStrip1.Visible = this.toolStrip1.Items.Count > 0;
        }

        private void Control_TextChanged(object sender, EventArgs e)
        {
            if (sender is Control control)
                this.Text = control.Text;
        }

        private void Control_ClientSizeChanged(object sender, EventArgs e)
        {
            System.Windows.Forms.Control control = sender as System.Windows.Forms.Control;
            this.Panel.Size = control.Size;
            this.Size = new Size(this.Panel.Width + 40, this.Panel.Height + 80);
            this.AutoScrollMinSize = new Size(this.Size.Width, this.Size.Height);
        }

        private void Form_Disposed(object sender, EventArgs e)
        {
            this.Dispose();
        }

        private void ButtonItemClick(object sender, ToolStripItemClickedEventArgs e)
        {
            IEditFormController controller = route.GetController();
            ISheetControl sheet = controller as ISheetControl;
            if (sheet != null && e.ClickedItem.Tag is IButtonItem item)
            {
                sheet.ItemClick(item);
            }
        }

        private void toolStrip1_SizeChanged(object sender, EventArgs e)
        {
            this.UpdateLocation();
        }

        private void toolStrip1_Paint(object sender, PaintEventArgs e)
        {
            Rectangle rect = new Rectangle(0, 0, this.toolStrip1.Width - 2, this.toolStrip1.Height - 2);
            e.Graphics.SetClip(rect);
        }

        private void toolStrip1_VisibleChanged(object sender, EventArgs e)
        {
            //this.UpdateLocation();
        }
    }
}
